package com.example.demo.config;

import com.alibaba.fastjson.JSON;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;

/**
 * @Author: renzh
 * @Description:
 * @Date: 10:10 2018-04-20
 * @Modified By:
 */
public class HandlerParameter implements HandlerMethodArgumentResolver {
    private final String BODY = "JSON_REQUEST_BODY";

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasMethodAnnotation(Rest.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
        if (!request.getContentType().contains("application/json")) {
            return null;
        }
        String pa = JSON.parseObject(getRequestBody(webRequest,request)).getString(parameter.getParameterName());
        //单值字符串类型解析问题--还有其他类型可能
        if(parameter.getParameterType() == String.class){
            return pa.toString();
        }
        return JSON.parseObject(pa.toString(),parameter.getNestedGenericParameterType());
    }

    private String getRequestBody(NativeWebRequest webRequest,HttpServletRequest request) {
        String st = (String) webRequest.getAttribute(BODY, NativeWebRequest.SCOPE_REQUEST);
        if (st==null){
            try {
                BufferedReader reader = request.getReader();
                StringBuilder sb = new StringBuilder();
                char[] buf = new char[1024];
                int rd;
                while((rd = reader.read(buf)) != -1){
                    sb.append(buf, 0, rd);
                }
                st = sb.toString();
                webRequest.setAttribute(BODY, st, NativeWebRequest.SCOPE_REQUEST);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return st;
    }
}
